home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / elm / elm2.4 / src / options.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-08  |  23.7 KB  |  836 lines

  1.  
  2. static char rcsid[] = "@(#)$Id: options.c,v 5.12 1993/05/08 20:25:33 syd Exp $";
  3.  
  4. /*******************************************************************************
  5.  *  The Elm Mail System  -  $Revision: 5.12 $   $State: Exp $
  6.  *
  7.  *             Copyright (c) 1986,1987 Dave Taylor
  8.  *             Copyright (c) 1988-1992 USENET Community Trust
  9.  *******************************************************************************
  10.  * Bug reports, patches, comments, suggestions should be sent to:
  11.  *
  12.  *    Syd Weinstein, Elm Coordinator
  13.  *    elm@DSI.COM            dsinc!elm
  14.  *
  15.  *******************************************************************************
  16.  * $Log: options.c,v $
  17.  * Revision 5.12  1993/05/08  20:25:33  syd
  18.  * Add sleepmsg to control transient message delays
  19.  * From: Syd
  20.  *
  21.  * Revision 5.11  1993/05/08  17:04:15  syd
  22.  * Jan's removal of tolower in alias.c breaks help for 'I'.  This fixes
  23.  * that and makes the help messages for characters that have printable
  24.  * synonyms on the alias and options screens consistent with the help files.
  25.  * From: dwolfe@pffft.sps.mot.com (Dave Wolfe)
  26.  *
  27.  * Revision 5.10  1993/04/21  01:35:36  syd
  28.  * NLS message ElmOptionBorderMenu should be ElmOptionBorderHelp in one place.
  29.  * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
  30.  *
  31.  * Revision 5.9  1993/04/12  03:05:59  syd
  32.  * The wrong NLS message was used in the option screen for the "A(l)ias Sorting".
  33.  * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
  34.  *
  35.  * Revision 5.8  1993/04/12  03:05:31  syd
  36.  * The primary editor didn't change at once when you entered a new value in
  37.  * the option screen.
  38.  * From: Jan Djarv <Jan.Djarv@sa.erisoft.se>
  39.  *
  40.  * Revision 5.7  1993/04/12  03:00:57  syd
  41.  * None of i, q, x, >, and ^L are recognized by the single character help
  42.  * on the options screen.  <return> causes the options screen to scroll
  43.  * because all non-printing characters are echoed by the error message.
  44.  * Options and alias help files didn't list all commands.
  45.  * From: dwolfe@pffft.sps.mot.com (Dave Wolfe)
  46.  *
  47.  * Revision 5.6  1993/02/03  19:06:31  syd
  48.  * Remove extra strchr/strcat/strcpy et al declarations
  49.  * From: Syd
  50.  *
  51.  * Revision 5.5  1993/02/03  17:12:53  syd
  52.  * move more declarations to defs.h, including sleep
  53.  * From: Syd
  54.  *
  55.  * Revision 5.4  1993/01/20  03:02:19  syd
  56.  * Move string declarations to defs.h
  57.  * From: Syd
  58.  *
  59.  * Revision 5.3  1992/11/07  19:37:21  syd
  60.  * Enhanced printing support.  Added "-I" to readmsg to
  61.  * suppress spurious diagnostic messages.
  62.  * From: chip@chinacat.unicom.com (Chip Rosenthal)
  63.  *
  64.  * Revision 5.2  1992/10/24  13:35:39  syd
  65.  * changes found by using codecenter on Elm 2.4.3
  66.  * From: Graham Hudspith <gwh@inmos.co.uk>
  67.  *
  68.  * Revision 5.1  1992/10/03  22:58:40  syd
  69.  * Initial checkin as of 2.4 Release at PL0
  70.  *
  71.  *
  72.  ******************************************************************************/
  73.  
  74. /** This set of routines allows the alteration of a number of paramaters
  75.     in the Elm mailer, including the following;
  76.  
  77.  
  78.     a)  arrow-cursor    <on or off>
  79.     b)  border for copy <string for left margin>
  80.     c)  calendar-file    <where to put calendar entries>
  81.     d)  display pager    <how to page messages>
  82.     e)  editor        <name of primary editor or "builtin">
  83.     f)  folder-dir    <folder directory>
  84.     h)  hold sent msgs  <on or off>
  85.   * i) (internal: quit to index screen)
  86.     j)  reply editor    <name of editor for replies>
  87.     k)  pause pager     <on or off>
  88.     l)  alias sort      <how to sort the alias display>
  89.     m)  menu-display    <on or off>
  90.     n)  names-only      <on or off>
  91.     o)  sent-mail    <file to save outbound message copies to>
  92.     p)  printmail    <how to print messages>
  93.   * q) (internal: quit to previous screen)
  94.     r)  reply copy      <on or off>
  95.     s)  sort-by        <how to sort folders>
  96.     t)  text editor     <name of ~e editor>
  97.     u)  user-level    <BEGINNER|INTERMEDIATE|EXPERT>
  98.     v)  visual editor    <name of ~v editor>
  99.     w)  want CC prompt  <on or off>
  100.   * x) (internal: exit ELM now)
  101.     y)  full_username    <your full user name for outgoing mail>
  102.     z)  zap sign dashes <on or off>
  103.     
  104.     And others as they seem useful.
  105.  
  106.     Formatting parameters:
  107.  
  108.     _)        Add a blank line
  109.     ^)        Put the title on this line
  110.  
  111.     A subset of the above parameters may be selected as the
  112.     o)ptions screen using the parameter "configoptions" which is
  113.     a string of letters representing the "key" letter for each
  114.     item as listed above.  The current default is "^_cdefsopyv_am_un".
  115.     The order of the options displayed is as listed in the string.
  116.  
  117. **/
  118.  
  119. #include "headers.h"
  120. #include "save_opts.h"
  121. #include "s_elm.h"
  122.  
  123. #ifdef BSD
  124. #undef tolower
  125. #endif
  126.  
  127. #undef onoff
  128. #define   onoff(n)    (n == 1? on_name : off_name)
  129.  
  130. extern char *alias_sort_name(), *sort_name();
  131.  
  132. char *level_name();
  133. static char *on_name = NULL;
  134. static char *off_name = NULL;
  135. static int resort = 0;
  136. static char temp[SLEN];    /* needed when an option is run through
  137.              * expand_env(), because that function
  138.              * is destructive of the original
  139.              */
  140.  
  141. static post_cal(f) int f; {strcpy(temp,raw_calendar_file); expand_env(calendar_file,temp);}
  142. static post_editor(f) int f; {strcpy(temp,raw_editor); expand_env(editor,temp);}
  143. static post_pager(f) int f; {
  144.     strcpy(temp, raw_pager); expand_env(pager, temp);
  145.     clear_pages=(equal(pager,"builtin+")||equal(pager,"internal+"));
  146.     }
  147. static post_folder(f) int f; {strcpy(temp,raw_folders); expand_env(folders,temp);}
  148. static post_sort(f) int f; {if (f) resort++;}
  149. static post_sent(f) int f; {strcpy(temp,raw_sentmail); expand_env(sent_mail,temp);}
  150. static post_print(f) int f; {strcpy(temp,raw_printout); expand_env(printout,temp);}
  151. static post_menu(f) int f; {headers_per_page=LINES-(mini_menu?13:8);}
  152.  
  153. opts_menu cfg_opts[] = {
  154.  
  155. {'a', "A)rrow cursor",    ElmOptionArrowMenu,  "arrow",    NULL,
  156. "This defines whether the ELM cursor is an arrow or a highlight bar.", ElmOptionArrowHelp},
  157.  
  158. {'b', "B)order on copy", ElmOptionBorderMenu,    "prefix",    NULL,
  159. "Left margin string (prefix) for reply and forward.", ElmOptionBorderHelp},
  160.  
  161. #ifdef ENABLE_CALENDAR
  162. {'c', "C)alendar file", ElmOptionCalendarMenu,    "calendar",    post_cal,
  163. "This is the file where calendar entries from messages are saved.", ElmOptionCalendarHelp},
  164. #endif
  165.  
  166. {'d', "D)isplay mail using", ElmOptionDisplayMenu,    "pager",    post_pager,
  167. "This is the program invoked to display individual messages (try 'builtin').", ElmOptionDisplayHelp},
  168.  
  169. {'e', "E)ditor (primary)", ElmOptionEditorMenu,    "editor",    post_editor,
  170. "This is the editor used for all outbound messages (may be 'builtin').", ElmOptionEditorHelp},
  171.  
  172. {'f', "F)older directory", ElmOptionFolderMenu,    "maildir",    post_folder,
  173. "This is the folders directory used when '=' (etc) is used in filenames.", ElmOptionFolderHelp},
  174.  
  175. {'h', "H)old sent message", ElmOptionHoldMenu,    "copy",        NULL,
  176. "Whether to save a copy of outbound messages in O)utbound folder.", ElmOptionHoldHelp},
  177.  
  178. {'j', "J) reply editor", ElmOptionJreplyMenu,    "alteditor",    NULL,
  179. "This is the editor that will be used for replies (Editor=\"builtin\").", ElmOptionJreplyHelp},
  180.  
  181. {'k', "K) pause after pager", ElmOptionKpauseMenu, "promptafter",    NULL,
  182. "Whether to pause (prompt) at end of message with display message pager.", ElmOptionKpauseHelp},
  183.  
  184. {'l', "A(l)ias Sorting", ElmOptionaLiasMenu,    "aliassortby",    post_sort,
  185. "This is used to specify the sorting criteria for the alias display.", ElmOptionaLiasHelp},
  186.  
  187. {'m', "M)enu display", ElmOptionMenuMenu,    "menu",        post_menu,
  188. "This determines if you have the mini-menu displayed or not.", ElmOptionMenuHelp},
  189.  
  190. {'n', "N)ames only", ElmOptionNameMenu,        "names",    NULL,
  191. "Whether to display the names and addresses on mail, or names only.", ElmOptionNameHelp},
  192.  
  193. {'o', "O)utbound mail saved", ElmOptionOutboundMenu, "sentmail",    post_sent,
  194. "This is where copies of outbound messages are saved automatically.", ElmOptionOutboundHelp},
  195.  
  196. {'p', "P)rint mail using", ElmOptionPrintMenu,    "print",    post_print,
  197. "This is the command used to print mail messages.", ElmOptionPrintHelp},
  198.  
  199. {'r', "R)eply copies msg", ElmOptionReplyMenu,    "autocopy",    NULL,
  200. "Whether to copy the message being replied to into the reply.", ElmOptionReplyHelp},
  201.  
  202. {'s', "S)orting criteria", ElmOptionSortMenu,    "sortby",    post_sort,
  203. "This is used to specify the sorting criteria for the folders.", ElmOptionSortHelp},
  204.  
  205. {'t', "T)ext editor (~e)", ElmOptionTextMenu,    "easyeditor",    NULL,
  206. "This is the editor that will be used by the ~e command (Editor=\"builtin\").", ElmOptionTextHelp},
  207.  
  208. {'u', "U)ser level", ElmOptionUserMenu,        "userlevel",    NULL,
  209. "The level of knowledge you have about the ELM mail system.", ElmOptionUserHelp},
  210.  
  211. {'v', "V)isual Editor (~v)", ElmOptionVisualMenu,    "visualeditor",    NULL,
  212. "This is the editor that will be used by the ~v command (Editor=\"builtin\").", ElmOptionVisualHelp},
  213.  
  214. {'w', "W)ant Cc: prompt", ElmOptionWantMenu,    "askcc",    NULL,
  215. "Whether to ask for \"Copies to:\" list when sending messages.", ElmOptionWantHelp},
  216.  
  217. {'y', "Y)our full name", ElmOptionYourMenu,    "fullname",    NULL,
  218. "When mail is sent out, this is what your full name will be recorded as.", ElmOptionYourHelp},
  219.  
  220. {'z', "Z) signature dashes", ElmOptionZdashMenu,    "sigdashes",    NULL,
  221. "Whether to print dashes before including signature on outbound messages.", ElmOptionZdashHelp},
  222.  
  223. { 0 } };
  224.  
  225. void init_opts_menu()
  226. {
  227.     register char *c;
  228.     register opts_menu *o;
  229.  
  230.     for (o = cfg_opts; o->parm; o++) {
  231.         c = catgets(elm_msg_cat, ElmSet, o->menu_msg, "~");
  232.         if (*c != '~')
  233.             o->menu = c;
  234.  
  235.         c = catgets(elm_msg_cat, ElmSet, o->one_liner_msg, "~");
  236.         if (*c != '~')
  237.             o->one_liner = c;
  238.     }
  239. }
  240.  
  241.  
  242. opts_menu *
  243. find_cfg_opts(c)
  244. int c;
  245. {
  246.     register opts_menu *o;
  247.  
  248.     for (o = cfg_opts; o->parm; o++) {
  249.     if (c == o->letter)
  250.         break;
  251.     }
  252.  
  253.     return(o->parm ? o : NULL);
  254. }
  255.  
  256.  
  257. char *
  258. one_liner_for(c)
  259. char c;
  260. {
  261.     opts_menu *o;
  262.  
  263.     o = find_cfg_opts(c);
  264.  
  265.     if (o)
  266.     return(o->one_liner);
  267.     else
  268.     return(NULL);
  269. }
  270.  
  271.  
  272. void
  273. display_options()
  274. {
  275.     /** Display all the available options.. **/
  276.     
  277.     int printed_title = FALSE;
  278.     register int y;
  279.     register opts_menu *o;
  280.     register char *s;
  281.     char buf[SLEN];
  282.     extern char *str_opt_nam();
  283.     
  284.     ClearScreen();
  285.  
  286.     for (s = config_options, y = 0; *s; s++, y++) {
  287.         if (*s == '^') {
  288.         printed_title = TRUE;
  289.         Centerline(y, catgets(elm_msg_cat, ElmSet, ElmOptionsEditor,
  290.             "-- ELM Options Editor --"));
  291.         continue;
  292.         }
  293.         if (*s == '_') {
  294.         continue;
  295.         }
  296.             o = find_cfg_opts(*s);
  297.             if (o != NULL && y<LINES-5) {
  298.         sprintf(buf,"%-20.20s : %%s", o->menu);
  299.         PutLine1(y, 0, buf, str_opt_nam(o->parm, FULL));
  300.         }
  301.         }
  302.     if (!printed_title) {
  303.         Centerline(LINES-5, catgets(elm_msg_cat, ElmSet, ElmOptionsEditor,
  304.         "-- ELM Options Editor --"));
  305.     }
  306. }
  307.  
  308.  
  309. void
  310. options_help()
  311. {
  312.     /** help menu for the options screen... **/
  313.  
  314.     char c, *ptr, *prompt;
  315.  
  316.     ClearLine(LINES-2);        /* clear option prompt message */
  317.     Centerline(LINES-3, catgets(elm_msg_cat, ElmSet, ElmPressKeyHelp,
  318.   "Press the key you want help for, '?' for a key list, or '.' to exit help"));
  319.  
  320.     lower_prompt(prompt = catgets(elm_msg_cat, ElmSet, ElmKeyPrompt, "Key : "));
  321.  
  322.     while ((c = ReadCh()) != '.') {
  323.       c = tolower(c);
  324.       if (c == '?') {
  325.          display_helpfile(OPTIONS_HELP);
  326.          display_options();
  327.          return;
  328.       }
  329.       if ((ptr = one_liner_for(c)) != NULL)
  330.         error2("%c = %s", c, ptr);
  331.       else
  332.         switch (c) {
  333.           case ctrl('L'): error(catgets(elm_msg_cat, ElmSet,
  334.                   ElmOptionCtrlLHelp,
  335.                   "^L = Rewrite the screen."));        break;
  336.  
  337.           case '>' : error(catgets(elm_msg_cat, ElmSet,ElmOptionGreaterHelp,
  338.                 "> = Save to elmrc file."));        break;
  339.  
  340.           case 'q' :
  341.           case 'i' : error(catgets(elm_msg_cat, ElmSet, ElmOptionReturnHelp,
  342.                 "i,q = Return from option menu."));    break;
  343.  
  344.           case 'x' : error(catgets(elm_msg_cat, ElmSet, ElmHelpQuickExit,
  345.                 "X = Exit leaving the folder untouched, unconditionally."));
  346.                 break;
  347.  
  348.           default: error(catgets(elm_msg_cat, ElmSet, ElmKeyIsntUsed,
  349.                 "That key isn't used in this section."));
  350.         }
  351.       lower_prompt(prompt);
  352.     }
  353.     ClearLine(LINES-3);        /* clear Press help key message */
  354.     ClearLine(LINES-1);        /* clear lower prompt message */
  355. }
  356.  
  357.  
  358. char *
  359. level_name(n)
  360. int n;
  361. {
  362.     /** return the 'name' of the level... **/
  363.  
  364.     switch (n) {
  365.       case 0 : return(catgets(elm_msg_cat, ElmSet, ElmBeginningUser,
  366.             "Beginning User   "));
  367.       case 1 : return(catgets(elm_msg_cat, ElmSet, ElmIntermediateUser,
  368.             "Intermediate User"));
  369.       default: return(catgets(elm_msg_cat, ElmSet, ElmExpertUser,
  370.             "Expert User      "));
  371.     }
  372. }
  373.  
  374. int
  375. options()
  376. {
  377.     /** change options... **/
  378.     /* return:
  379.      *    > 0    if resort was done - to indicate we might need to
  380.      *         change the page of our headers as a consequence
  381.      *        of the new sort order
  382.      *    < 0    if user entered 'X' to quit elm immediately
  383.      *    0    otherwise
  384.      */
  385.  
  386.     int    ch,
  387.         y;
  388.     opts_menu *o;
  389.     char    *prompt;
  390.  
  391.     if (on_name == NULL) {
  392.         on_name = catgets(elm_msg_cat, ElmSet, ElmOn, "ON ");
  393.         off_name = catgets(elm_msg_cat, ElmSet, ElmOff, "OFF");
  394.     }
  395.     if (!config_options[0]) {
  396. #ifdef ENABLE_CALENDAR
  397.         strcpy(config_options,"^_cdefsopyv_am_un");
  398. #else
  399.         strcpy(config_options,"^_defsopyv_am_un");
  400. #endif
  401.     }
  402.  
  403.  
  404.     resort = 0;
  405.     prompt = catgets(elm_msg_cat, ElmSet, ElmPrompt, "Command: ");
  406.     display_options();
  407.  
  408.     clearerr(stdin);
  409.  
  410.     while(1) {
  411.       ClearLine(LINES-4);
  412.  
  413.       Centerline(LINES-4, catgets(elm_msg_cat, ElmSet, ElmSelectOptionLetter,
  414.  "Select letter of option line, '>' to save, or 'i' to return to index."));
  415.  
  416.       PutLine0(LINES-2, 0, prompt);
  417.  
  418.       ch = ReadCh();
  419.       ch = tolower(ch);
  420.  
  421.       clear_error();    /* remove possible "sorting" message etc... */ 
  422.  
  423.       if (index(config_options, ch)) {
  424.           y = index(config_options,ch) - config_options;
  425.               o = find_cfg_opts(ch);
  426.               if (o != NULL && y < LINES-5) {
  427.           one_liner(o->one_liner);
  428.           y = info_enter(o->parm, y, 23, FALSE, FALSE);
  429.           if (o->post)
  430.               (o->post)(y);
  431.           } else
  432.               error(catgets(elm_msg_cat, ElmSet, ElmCommandUnknown,
  433.             "Command unknown!"));
  434.       } else {
  435.           one_liner(NULL);
  436.           switch (ch) {
  437.         case '?' : options_help(); 
  438.                    PutLine0(LINES-2,0, prompt);            break;
  439.        
  440.         case '>' : printf(catgets(elm_msg_cat, ElmSet, ElmSaveOptions,
  441.             "Save options in .elm/elmrc..."));
  442.                fflush(stdout);    save_options();        break;
  443.  
  444.         case 'x' :    return(-1);    /* exit elm */
  445.         case 'q' :    /* pop back up to previous level, in this case == 'i' */
  446.         case 'i' :  /* return to index screen */
  447.             return(resort ? 1 : 0);
  448.         case ctrl('L'): display_options();                break;
  449.         default: error(catgets(elm_msg_cat, ElmSet, ElmCommandUnknown,
  450.             "Command unknown!"));
  451.           }
  452.       }
  453.     }
  454. }
  455.  
  456.  
  457.  
  458. on_or_off(var, x, y)
  459. int *var, x,y;
  460. {
  461.     /** 'var' field at x.y toggles between on and off... **/
  462.  
  463.     char ch;
  464.  
  465.          PutLine0(x, y+6, catgets(elm_msg_cat, ElmSet, ElmUseSpaceToToggle,
  466.         "(use <space> to toggle, any other key to leave)"));
  467.  
  468.     MoveCursor(x,y+3);    /* at end of value... */
  469.  
  470.     do {
  471.       ch = ReadCh();
  472.  
  473.       if (ch == SPACE) {
  474.         *var = ! *var;
  475.         PutLine0(x,y, onoff(*var));
  476.       }
  477.     } while (ch == SPACE);
  478.  
  479.     MoveCursor(x,y+4);     CleartoEOLN();    /* remove help prompt */
  480. }
  481.  
  482.  
  483. switch_user_level(ulevel, x, y)
  484. int *ulevel, x, y;
  485. {
  486.     /** step through possible user levels... **/
  487.  
  488.          PutLine0(x, y+20, catgets(elm_msg_cat, ElmSet, ElmSpaceToChange,
  489.         "<space> to change"));
  490.  
  491.     MoveCursor(x,y);    /* at end of value... */
  492.  
  493.     while (ReadCh() == ' ') {
  494.       *ulevel = (*ulevel >= 2? 0 : *ulevel + 1);
  495.       PutLine1(x,y, "%s", level_name(*ulevel));
  496.     }
  497.  
  498.     MoveCursor(x,y+20);     CleartoEOLN();    /* remove help prompt */
  499. }
  500.  
  501.  
  502. change_sort(var, x, y)
  503. int *var;
  504. int x,y;
  505. {
  506.     /** change the sorting scheme... **/
  507.     /** return !0 if new sort order, else 0 **/
  508.     
  509.     int last_sortby,    /* so we know if it changes... */
  510.         sign = 1;        /* are we reverse sorting??    */
  511.     int ch;            /* character typed in ...      */
  512.  
  513. /*    *var = sortby;     or...    *var == sortby;     */
  514.     last_sortby = sortby;    /* remember current ordering   */
  515.  
  516.     PutLine0(x, COLUMNS-29, catgets(elm_msg_cat, ElmSet, ElmSpaceForNext,
  517.         "(SPACE for next, or R)everse)"));
  518.     sort_one_liner(sortby);
  519.     MoveCursor(x, y);
  520.  
  521.     do {
  522.       ch = ReadCh();
  523.       ch = tolower(ch);
  524.       switch (ch) {
  525.         case SPACE : if (sortby < 0) { 
  526.                    sign = -1; 
  527.                    sortby = - sortby; 
  528.                }
  529.              else sign = 1;        /* insurance! */
  530.                sortby = sign * ((sortby + 1) % (STATUS+2));
  531.              if (sortby == 0) sortby = sign;  /* snicker */
  532.                PutLine0(x, y, sort_name(PAD));
  533.              sort_one_liner(sortby);
  534.                MoveCursor(x, y);
  535.              break;
  536.  
  537.         case 'r'   : sortby = - sortby;
  538.                PutLine0(x, y, sort_name(PAD));
  539.              sort_one_liner(sortby);
  540.                MoveCursor(x, y);
  541.      }
  542.         } while (ch == SPACE || ch == 'r');
  543.  
  544.     MoveCursor(x, COLUMNS-30);    CleartoEOLN();
  545.  
  546.     if (sortby != last_sortby) {
  547.       error(catgets(elm_msg_cat, ElmSet, ElmResortingFolder,
  548.         "Resorting folder..."));
  549.       if (sleepmsg > 0)
  550.         sleep((sleepmsg + 1) / 2);
  551.       sort_mailbox(message_count, 0);
  552.     }
  553.     ClearLine(LINES-2);        /* clear sort_one_liner()! */
  554.     *var=sortby;
  555.     sortby=last_sortby;
  556.     return(*var-sortby);
  557. }
  558.  
  559.  
  560. one_liner(string)
  561. char *string;
  562. {
  563.     /** A single-line description of the selected item... **/
  564.  
  565.     ClearLine(LINES-4);
  566.     if (string)
  567.         Centerline(LINES-4, string);
  568. }
  569.  
  570.  
  571. sort_one_liner(sorting_by)
  572. int sorting_by;
  573. {
  574.     /** A one line summary of the particular sorting scheme... **/
  575.  
  576.     ClearLine(LINES-2);
  577.  
  578.     switch (sorting_by) {
  579.       
  580.       case REVERSE SENT_DATE:    Centerline(LINES-2,
  581.                 catgets(elm_msg_cat, ElmSet, ElmSortRSentDate,
  582. "This sort will order most-recently-sent to least-recently-sent"));
  583.                 break;
  584.       case REVERSE RECEIVED_DATE:    Centerline(LINES-2,
  585.                 catgets(elm_msg_cat, ElmSet, ElmSortRRecvDate,
  586. "This sort will order most-recently-received to least-recently-received"));
  587.                 break;
  588.       case REVERSE MAILBOX_ORDER:    Centerline(LINES-2,
  589.                 catgets(elm_msg_cat, ElmSet, ElmSortRMailbox,
  590. "This sort will order most-recently-added-to-folder to least-recently"));
  591.                 break;
  592.       case REVERSE SENDER:        Centerline(LINES-2,
  593.                 catgets(elm_msg_cat, ElmSet, ElmSortRSender,
  594. "This sort will order by sender name, in reverse alphabetical order"));
  595.                 break;
  596.       case REVERSE SIZE:        Centerline(LINES-2,
  597.                 catgets(elm_msg_cat, ElmSet, ElmSortRSize,
  598. "This sort will order messages by longest to shortest"));
  599.                 break;
  600.       case REVERSE SUBJECT:        Centerline(LINES-2,
  601.                 catgets(elm_msg_cat, ElmSet, ElmSortRSubject,
  602. "This sort will order by subject, in reverse alphabetical order"));
  603.                 break;
  604.       case REVERSE STATUS:        Centerline(LINES-2,
  605.                 catgets(elm_msg_cat, ElmSet, ElmSortRStatus,
  606. "This sort will order by reverse status - Deleted through Tagged..."));
  607.                 break;
  608.       case SENT_DATE:        Centerline(LINES-2,
  609.                 catgets(elm_msg_cat, ElmSet, ElmSortSentDate,
  610. "This sort will order least-recently-sent to most-recently-sent"));
  611.                 break;
  612.       case RECEIVED_DATE:        Centerline(LINES-2,
  613.                 catgets(elm_msg_cat, ElmSet, ElmSortRecvDate,
  614. "This sort will order least-recently-received to most-recently-received"));
  615.                 break;
  616.       case MAILBOX_ORDER:        Centerline(LINES-2,
  617.                 catgets(elm_msg_cat, ElmSet, ElmSortMailbox,
  618. "This sort will order least-recently-added-to-folder to most-recently"));
  619.                 break;
  620.       case SENDER:            Centerline(LINES-2,
  621.                 catgets(elm_msg_cat, ElmSet, ElmSortSender,
  622. "This sort will order by sender name"));
  623.                 break;
  624.       case SIZE:            Centerline(LINES-2,
  625.                 catgets(elm_msg_cat, ElmSet, ElmSortSize,
  626. "This sort will order messages by shortest to longest"));
  627.                 break;
  628.       case SUBJECT:            Centerline(LINES-2,
  629.                 catgets(elm_msg_cat, ElmSet, ElmSortSubject,
  630. "This sort will order messages by subject"));
  631.                 break;
  632.       case STATUS:            Centerline(LINES-2,
  633.                 catgets(elm_msg_cat, ElmSet, ElmSortStatus,
  634. "This sort will order by status - Tagged through Deleted..."));
  635.                 break;
  636.     }
  637. }
  638.  
  639.  
  640.  
  641. change_alias_sort(var, x, y)
  642. int *var;
  643. int x,y;
  644. {
  645.     /** change the sorting scheme... **/
  646.     /** return !0 if new sort order, else 0 **/
  647.     
  648.     int last_sortby,    /* so we know if it changes... */
  649.         sign = 1;        /* are we reverse sorting??    */
  650.     int ch;            /* character typed in ...      */
  651.  
  652. /*    *var = alias_sortby;     or...    *var == alias_sortby;     */
  653.     last_sortby = alias_sortby;    /* remember current ordering   */
  654.  
  655.     PutLine0(x, COLUMNS-29, catgets(elm_msg_cat, ElmSet, ElmSpaceForNext,
  656.         "(SPACE for next, or R)everse)"));
  657.     alias_sort_one_liner(alias_sortby);
  658.     MoveCursor(x, y);
  659.  
  660.     do {
  661.       ch = ReadCh();
  662.       ch = tolower(ch);
  663.       switch (ch) {
  664.         case SPACE : if (alias_sortby < 0) { 
  665.                    sign = -1; 
  666.                    alias_sortby = - alias_sortby; 
  667.                }
  668.              else sign = 1;        /* insurance! */
  669.                alias_sortby = sign * ((alias_sortby + 1)
  670.                                     % (LAST_ALIAS_SORT+1));
  671.              if (alias_sortby == 0) alias_sortby = sign;
  672.                PutLine0(x, y, alias_sort_name(PAD));
  673.              alias_sort_one_liner(alias_sortby);
  674.                MoveCursor(x, y);
  675.              break;
  676.  
  677.         case 'r'   : alias_sortby = - alias_sortby;
  678.                PutLine0(x, y, alias_sort_name(PAD));
  679.              alias_sort_one_liner(alias_sortby);
  680.                MoveCursor(x, y);
  681.      }
  682.         } while (ch == SPACE || ch == 'r');
  683.  
  684.     MoveCursor(x, COLUMNS-30);    CleartoEOLN();
  685.  
  686.     if (alias_sortby != last_sortby) {
  687.       error(catgets(elm_msg_cat, ElmSet, ElmResortingAliases,
  688.             "Resorting aliases..."));
  689.       if (sleepmsg > 0)
  690.         sleep((sleepmsg + 1) / 2);
  691.       main_state();
  692.       sort_aliases(message_count, FALSE);
  693.       main_state();
  694.     }
  695.     ClearLine(LINES-2);        /* clear alias_sort_one_liner()! */
  696.     *var=alias_sortby;
  697.     alias_sortby=last_sortby;
  698.     return(*var-alias_sortby);
  699. }
  700.  
  701. alias_sort_one_liner(sorting_by)
  702. int sorting_by;
  703. {
  704.     /** A one line summary of the particular sorting scheme... **/
  705.  
  706.     ClearLine(LINES-2);
  707.  
  708.     switch (sorting_by) {
  709.       
  710.       case REVERSE ALIAS_SORT:    Centerline(LINES-2,
  711.                 catgets(elm_msg_cat, ElmSet, ElmASortRAlias,
  712. "This sort will order by alias name, in reverse alphabetical order"));
  713.                     break;
  714.       case REVERSE NAME_SORT:    Centerline(LINES-2,
  715.                 catgets(elm_msg_cat, ElmSet, ElmASortRName,
  716. "This sort will order by user (real) name, in reverse alphabetical order"));
  717.                     break;
  718.       case REVERSE TEXT_SORT:    Centerline(LINES-2,
  719.                 catgets(elm_msg_cat, ElmSet, ElmASortRText,
  720. "This sort will order aliases in the reverse order as listed in aliases.text"));
  721.                     break;
  722.  
  723.       case ALIAS_SORT:        Centerline(LINES-2,
  724.                 catgets(elm_msg_cat, ElmSet, ElmASortAlias,
  725. "This sort will order by alias name"));
  726.                     break;
  727.       case NAME_SORT:        Centerline(LINES-2,
  728.                 catgets(elm_msg_cat, ElmSet, ElmASortName,
  729. "This sort will order by user (real) name"));
  730.                     break;
  731.       case TEXT_SORT:        Centerline(LINES-2,
  732.                 catgets(elm_msg_cat, ElmSet, ElmASortText,
  733. "This sort will order aliases in the order as listed in aliases.text"));
  734.                     break;
  735.  
  736.     }
  737. }
  738.  
  739. /*
  740.  * This routine is a "shell" to optionally_enter(), etc. so that
  741.  * we can use save_info structure and tag the param as being changed
  742.  * locally (so we know to save it to the .elm/elmrc file).
  743.  */
  744. info_enter(name, ypos, xpos, append_current, passwd)
  745. char *name;
  746. int ypos, xpos, append_current, passwd;
  747. {
  748.     register int x,q;
  749.     char buffer[SLEN];
  750.     int number;
  751.  
  752.     for (x = 0; x < NUMBER_OF_SAVEABLE_OPTIONS; x++) {
  753.         q = strcmp(name, save_info[x].name);
  754.         if (q <= 0)
  755.             break;
  756.     }
  757.  
  758.     if (q)
  759.         return(1);
  760.  
  761.     switch(save_info[x].flags & DT_MASK) {
  762.         case DT_STR:
  763.         strcpy(buffer, SAVE_INFO_STR(x));
  764.         if (save_info[x].flags & FL_NOSPC) {
  765.             register char *s;
  766.             for (s = buffer; *s; ++s)
  767.             if (*s==' ')
  768.                 *s='_';
  769.         }
  770.  
  771.         optionally_enter(buffer, ypos, xpos, append_current, passwd);
  772.  
  773.         if (save_info[x].flags & FL_NOSPC) {
  774.             register char *s;
  775.             for (s=buffer; *s; ++s)
  776.             if (*s=='_')
  777.                 *s=' ';
  778.         }
  779.  
  780.         if (equal(buffer, SAVE_INFO_STR(x)))
  781.             break;
  782.  
  783.         strcpy(SAVE_INFO_STR(x), buffer);
  784.         q++;
  785.         break;
  786.  
  787.         case DT_SRT:
  788.         number = *SAVE_INFO_SRT(x);
  789.         if (change_sort(&number, ypos, xpos) != 0) {
  790.             *SAVE_INFO_SRT(x) = number;
  791.             ++q;
  792.             }
  793.         break;
  794.  
  795.         case DT_ASR:
  796.         number = *SAVE_INFO_ASR(x);
  797.         if (change_alias_sort(&number, ypos, xpos) != 0) {
  798.             *SAVE_INFO_ASR(x) = number;
  799.             ++q;
  800.             }
  801.         break;
  802.  
  803.         case DT_NUM:
  804.         number = *SAVE_INFO_NUM(x);
  805.         if (equal(name, "userlevel")) {
  806.             switch_user_level(&number, ypos, xpos);
  807.             }
  808.  
  809.         if (number == *SAVE_INFO_NUM(x))
  810.             break;
  811.  
  812.         *SAVE_INFO_NUM(x) = number;
  813.         ++q;
  814.         break;
  815.  
  816.         case DT_BOL:
  817.         number = *SAVE_INFO_BOL(x);
  818.         on_or_off(&number, ypos, xpos);
  819.         if (number == *SAVE_INFO_BOL(x))
  820.             break;
  821.  
  822.         *SAVE_INFO_BOL(x) = number;
  823.         ++q;
  824.         break;
  825.  
  826.         default:
  827.         break;
  828.         }
  829.  
  830.     if (q)
  831.         save_info[x].flags |= FL_LOCAL;
  832.  
  833.     return(q != 0);
  834. }
  835.  
  836.